#include "BaseDialog.h"

#include <QtGui/QApplication>

#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QPushButton>

using namespace std;

DebugLevelType BaseDialog::interne( BLANK );

/**
 * Constructeur par défaut. Le nom et l'éventuel parent du QDialog
 * sont alors copiés, puis les autres champs sont initialisés.
 *
 * @param[in] nom permet d'identifier le widget
 * @param[in] parent pointeur sur le widget parent (orphelin par défaut)
 */
BaseDialog::BaseDialog( const QString& nom, QWidget *parent )
  :  QDialog( parent ), ADDObjetBase( nom.toStdString() ), OK( true )
{
  setObjectName( nom );

  fenetreLayout = new QVBoxLayout( this );
  fenetreLayout -> setObjectName( QString::fromUtf8("Layout de la fenêtre") );
  boutonsLayout = new QHBoxLayout( fenetreLayout -> widget() );
  boutonsLayout -> setObjectName( QString::fromUtf8("Layout des boutons") );
}

/**
 * Constructeur de copie, permet de dupliquer une instance. Il faut
 * faire attention aux boutons de l'instance "source" de BaseDialog.
 *
 * @param[in] dial instance de BaseDialog que l'on veut copier.
 */
BaseDialog::BaseDialog( const BaseDialog& dial )
  : QDialog( static_cast< QWidget* >( dial.parent() ) ),
    ADDObjetBase( dial.objectName().toStdString() ), OK( true )
{
  setObjectName( dial.objectName() );

  fenetreLayout = new QVBoxLayout( this );
  fenetreLayout -> setObjectName( QString::fromUtf8("Layout de la fenêtre") );
  boutonsLayout = new QHBoxLayout( fenetreLayout -> widget() );
  boutonsLayout -> setObjectName( QString::fromUtf8("Layout des boutons") );

  vector< QPushButton* >::const_iterator it, btEnd( dial.boutons.end() );

  for (it = dial.boutons.begin(); it != btEnd; it++)
    boutons.push_back( new QPushButton( (*it) -> text(), this ) );
}

/**
 * Destructeur, ne fait rien de spécial. La gestion de la mémoire
 * est laissée au mécanisme natif de Qt.
 *
 * Le destructeur est déclaré virtual pour assurer une destruction
 * propre des différents objets.
 */
BaseDialog::~BaseDialog()
{}

/**
 * Permet de modifier le niveau de sortie BaseDialog::interne.
 *
 * @param[in] level nouvelle valeur du niveau de sortie BaseDialog::interne.
 */
void BaseDialog::setLevel( const DebugLevelType& level, const unsigned& )
{
  interne = level;
}

/**
 * Insère les boutons contenus dans le conteneur boutons dans le
 * layout boutonsLayout. Ne doit pas être appelé directement, sinon
 * les boutons peuvent être mal placés!\n
 *
 * Le niveau de sortie est paramétré par BaseDialog::interne :\n
 * - \e FUNC affiche les messages de début et de fin de méthode.
 */
void BaseDialog::setBoutonsLayout()
{
  /*Debug::*/empileNiveau( &interne );
  func() << "BaseDialog::setBoutonsLayout -> début" << endmsg;

  unsigned int i, taille( boutons.size() );

  for (i = 0; i < taille; i++)
    boutonsLayout -> addWidget(boutons[i]);

  fenetreLayout -> insertLayout(-1, boutonsLayout);

  func() << "BaseDialog::setBoutonsLayout -> fin" << endmsg;
  /*Debug::*/depileNiveau();
}

/**
 * Ajoute la barre des boutons, en faisant appel à setBoutonsLayout(),
 * puis assigne le layout fenetreLayout au widget courant.\n
 *
 * Le niveau de sortie est paramétré par BaseDialog::interne :\n
 * - \e FUNC affiche les messages de début et de fin de méthode.
 */
void BaseDialog::setFenetreLayout()
{
  /*Debug::*/empileNiveau( &interne );
  func() << "BaseDialog::setFenetreLayout -> début" << endmsg;

  setBoutonsLayout();

  this -> setLayout( fenetreLayout );

  func() << "BaseDialog::setFenetreLayout -> fin" << endmsg;
  /*Debug::*/depileNiveau();
}

/**
 * Est connecté au bouton "OK", approuve le choix fait. Le booléen OK
 * est mis à \e true, et on appelle le slot close().
 */
void BaseDialog::fermer()
{
  OK = true;

  close();
}

/**
 * Est connecté au bouton "Annuler" et annule le choix fait. Le
 * booléen OK est mis à \e false, et on appelle le slot close().
 */
void BaseDialog::annuler()
{
  OK = false;

  close();
}
